package GUI;

import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JScrollBar;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

import transport.Constants;
import network.*;
import application.chat.Chat;

public class ChatGUI extends JFrame implements ActionListener, KeyListener {

	JButton connectButton = new JButton("Connect");
	JButton listenButton = new JButton("Listen");
	JButton disconnectButton = new JButton("Disconnect");

	JTextArea typeArea = new JTextArea();
	JScrollPane typePane = new JScrollPane();

	JTextArea textArea = new JTextArea();
	JScrollBar scrollBar = new JScrollBar();

	Chat chat;

	public static void main(String[] args) {
		ChatGUI gui = new ChatGUI();

		gui.run();
	}

	public ChatGUI() {
		this.setSize(1200, 800);
		this.setLocation(300, 200);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setContentPane(new Container());
		chat = new Chat("Gijs", this);

	}

	private void run() {

		this.setResizable(false);

		connectButton.setSize(400, 150);
		listenButton.setSize(400, 150);
		disconnectButton.setSize(400, 150);

		connectButton.setLocation(700, 125);
		listenButton.setLocation(700, 300);
		disconnectButton.setLocation(700, 500);

		connectButton.addActionListener(this);
		listenButton.addActionListener(this);
		disconnectButton.addActionListener(this);

		this.add(connectButton);
		this.add(disconnectButton);
		this.add(listenButton);

		disconnectButton.setEnabled(false);
		JScrollPane textPane = new JScrollPane(textArea);
		LineBorder border = new LineBorder(Color.BLACK);
		textPane.setSize(500, 325);
		// textArea.setSize(480, 325);

		textPane.setLocation(100, 125);
		scrollBar.setSize(25, 325);
		// textPane.add(textArea);

		textPane.setBackground(Color.WHITE);
		textPane.setVisible(true);
		textArea.setVisible(true);
		textArea.setLineWrap(true);
		textArea.setBorder(border);
		textPane.setBorder(border);
		textArea.setEditable(false);
		textPane.setVerticalScrollBar(scrollBar);

		scrollBar.setEnabled(true);
		typePane.add(typeArea);
		typePane.setBackground(Color.WHITE);
		typeArea.setBackground(Color.WHITE);
		typePane.setSize(500, 150);
		typePane.setLocation(100, 500);
		typeArea.setSize(500, 150);
		typeArea.setLocation(100, 500);
		typeArea.setBorder(border);
		typeArea.setVisible(true);
		typePane.setVisible(true);
		typeArea.addKeyListener(this);
		this.add(typeArea);
		this.add(textPane);
		scrollBar.setVisible(true);
		this.setBackground(Color.BLUE);
		this.setVisible(true);
		textPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		textPane.setWheelScrollingEnabled(true);
		JLabel dummy = new JLabel();
		this.add(dummy);

	}

	public void out(String text) {
		textArea.append(text + '\n');

	}

	public void sysOut(String text) {
		out(text);
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {

		if (arg0.getSource().equals(connectButton)) {
			connectButton.setEnabled(false);
			listenButton.setEnabled(false);
			ConnectFrame conFrame = new ConnectFrame(this);
		} else if (arg0.getSource().equals(listenButton)) {
			listenButton.setEnabled(false);
			connectButton.setEnabled(false);
			ListenFrame lisFrame = new ListenFrame(this);

		} else if (arg0.getSource().equals(disconnectButton)) {
			chat.disconnect();
			sysOut("Sent a FIN to other side. Closing connection in 10 seconds");
		}

	}

	public void connected() {
		disconnectButton.setEnabled(true);
	}

	@Override
	public void keyPressed(KeyEvent arg0) {
		if (arg0.getKeyChar() == '\n') {
			if (chat.isConnected()) {
				chat.send(typeArea.getText());
			} else {
				sysOut("You are not connected yet!");
			}
			typeArea.setText("");
		}
	}

	@Override
	public void keyReleased(KeyEvent arg0) {

		if (arg0.getKeyChar() == '\n') {
			typeArea.setText("");
		}

	}

	@Override
	public void keyTyped(KeyEvent arg0) {

		if (arg0.getKeyChar() == '\n') {
			typeArea.setText("");
		}
	}

	public void resetConnectButtons() {
		connectButton.setEnabled(true);
		listenButton.setEnabled(true);
		disconnectButton.setEnabled(false);
		// frame.dispose();

	}

	public class ConnectFrame extends JFrame implements ActionListener {
		JButton button = new JButton("Connect!");
		JTextArea portArea = new JTextArea();
		JTextArea TPAArea = new JTextArea();
		LineBorder border = new LineBorder(Color.BLACK);

		JLabel portLabel = new JLabel("Poortnummer:");
		JLabel TPALabel = new JLabel("TPA om mee te verbinden:");
		JLabel errorLabel = new JLabel("");
		ChatGUI gui;

		public ConnectFrame(ChatGUI gui) {
			this.setSize(500, 250);
			this.setLocation(700, 125);
			this.gui = gui;
			this.setVisible(true);

			this.add(button);
			this.add(portArea);
			this.add(TPAArea);
			this.add(errorLabel);
			this.add(portLabel);
			this.add(TPALabel);
			this.setResizable(false);
			TPALabel.setSize(150, 25);
			portLabel.setSize(150, 25);
			TPALabel.setLocation(25, 25);
			portLabel.setLocation(25, 125);
			errorLabel.setSize(150, 50);
			errorLabel.setLocation(225, 25);
			button.setSize(150, 50);
			portArea.setSize(150, 25);
			TPAArea.setSize(150, 25);
			button.setLocation(225, 125);
			TPAArea.setLocation(25, 50);
			portArea.setLocation(25, 150);
			portArea.setBorder(border);
			TPAArea.setBorder(border);
			errorLabel.setVisible(true);
			JLabel dummy = new JLabel();
			button.addActionListener(this);
			this.add(dummy);

		}

		public void run() {
			try {
				if (Integer.parseInt(TPAArea.getText()) < network.Constants.TPA_LENGTH) {
					try {
						if (Integer.parseInt(portArea.getText()) < Constants.PORT_MAX) {
							chat.connect(Integer.parseInt(portArea.getText()),
									Integer.parseInt(TPAArea.getText()));
							sysOut("Requesting a connection on port "
									+ portArea.getText() + ". And with TPA "
									+ TPAArea.getText());
							this.dispose();
						} else {
							error("Poortnummer te hoog!");
						}
					} catch (NumberFormatException e) {
						error("Poortnummer moet een" + '\n' + " getal zijn!");
					}
				} else {
					error("TPA-adres te hoog!");
				}
			} catch (NumberFormatException e) {
				error("TPA-nummer moet een getal zijn!");
			}
		}

		public void error(String e) {
			errorLabel.setText(e);
			errorLabel.setVisible(true);
		}

		@Override
		public void actionPerformed(ActionEvent arg0) {
			error("FOUT!!");
			run();

		}
	}

	public class ListenFrame extends JFrame implements ActionListener {
		JButton button = new JButton("Connect!");
		JTextArea portArea = new JTextArea();
		LineBorder border = new LineBorder(Color.BLACK);
		JLabel portLabel = new JLabel("Poortnummer:");
		JLabel errorLabel = new JLabel("");
		ChatGUI gui;

		public ListenFrame(ChatGUI gui) {
			// TODO Chat toevoegen
			this.setSize(500, 200);
			this.setLocation(700, 125);
			this.gui = gui;
			this.setVisible(true);
			this.add(portArea);
			this.add(portLabel);
			this.add(errorLabel);
			this.add(button);
			this.setResizable(false);
			portArea.setSize(150, 25);
			portArea.setLocation(25, 100);
			portArea.setBorder(border);
			button.setSize(150, 50);
			button.setLocation(225, 75);
			errorLabel.setLocation(225, 25);
			errorLabel.setSize(200, 50);
			portLabel.setSize(150, 25);
			portLabel.setLocation(25, 75);
			button.addActionListener(this);
			JLabel dummy = new JLabel();
			this.add(dummy);

		}

		public void run() {

			try {
				if (Integer.parseInt(portArea.getText()) < Constants.PORT_MAX) {
					chat.listen(Integer.parseInt(portArea.getText()));
					sysOut("Started listening on port " + portArea.getText()
							+ ". Looking for connections");
					this.dispose();
				} else {
					error("Poortnummer te hoog!");
				}
			} catch (NumberFormatException e) {
				error("Poortnummer moet een" + '\n' + " getal zijn!");
			}

		}

		public void error() {
			errorLabel.setText("FOUT!!");
		}

		public void error(String e) {
			errorLabel.setText(e);
			errorLabel.setVisible(true);
		}

		public void actionPerformed(ActionEvent e) {

			run();
		}

	}

}
